﻿using Aliyun.OSS;
using Aliyun.OSS.Common;
using LPP.Entity.Work;
using LPP.EntityFrameworkCore;
using LPP.Service.WorkerService;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Threading.Channels;
using System.Transactions;

public class ImageUploadService : IImageUploadService
{
    private readonly IConfiguration _configuration;
    private readonly ILogger<ImageUploadService> _logger;
    private readonly IOss _ossClient;
    private readonly string _bucketName;
    private readonly string _baseUrl;
    private readonly SqlDbContext _context; // 添加数据库上下文

    public ImageUploadService(
        IConfiguration configuration,
        SqlDbContext context,
        ILogger<ImageUploadService> logger)
    {
        _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
        _context = context ?? throw new ArgumentNullException(nameof(context));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));

        try
        {
            // 从配置中读取OSS配置
            var accessKeyId = _configuration["Aliyun:OSS:AccessKeyId"];
            var accessKeySecret = _configuration["Aliyun:OSS:AccessKeySecret"];
            var endpoint = _configuration["Aliyun:OSS:Endpoint"]?.ToLower().Trim();
            _bucketName = _configuration["Aliyun:OSS:BucketName"];
            _baseUrl = _configuration["Aliyun:OSS:BaseUrl"];

            // 记录配置（不要记录 AccessKeySecret）
            _logger.LogInformation(
                "OSS Configuration - Endpoint: {Endpoint}, BucketName: {BucketName}, AccessKeyId: {AccessKeyId}",
                endpoint, _bucketName, accessKeyId);

            // 验证配置
            if (string.IsNullOrEmpty(accessKeyId))
                throw new InvalidOperationException("OSS AccessKeyId 未配置");
            if (string.IsNullOrEmpty(accessKeySecret))
                throw new InvalidOperationException("OSS AccessKeySecret 未配置");
            if (string.IsNullOrEmpty(endpoint))
                throw new InvalidOperationException("OSS Endpoint 未配置");
            if (string.IsNullOrEmpty(_bucketName))
                throw new InvalidOperationException("OSS BucketName 未配置");
            if (string.IsNullOrEmpty(_baseUrl))
                throw new InvalidOperationException("OSS BaseUrl 未配置");

            // 确保endpoint格式正确
            endpoint = endpoint.Replace("http://", "").Replace("https://", "");

            // 初始化OSSClient
            var clientConfig = new ClientConfiguration();
            _ossClient = new OssClient(endpoint, accessKeyId, accessKeySecret, clientConfig);

            // 验证连接
            if (!_ossClient.DoesBucketExist(_bucketName))
            {
                throw new InvalidOperationException($"Bucket {_bucketName} 不存在");
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "初始化 OSS 客户端失败");
            throw;
        }
    }

    public async Task<string> UploadImageAsync(IFormFile file, string workerId, string type)
    {
        try
        {
            // 先上传到OSS
            var imageUrl = await UploadToOss(file);
            _logger.LogInformation("文件已成功上传到OSS: {Url}", imageUrl);

            // 使用事务更新数据库
            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    // 获取工人信息
                    var worker = await _context.Workers
                        .AsTracking()
                        .FirstOrDefaultAsync(w => w.WorkerID == int.Parse(workerId));

                    if (worker == null)
                    {
                        throw new InvalidOperationException($"未找到ID为 {workerId} 的工人信息");
                    }

                    // 更新工人信息
                    if (type.ToLower() == "front")
                    {
                        worker.IdCardFront = imageUrl;
                        _logger.LogInformation("更新正面照片: WorkerId={WorkerId}, Url={Url}", workerId, imageUrl);
                    }
                    else if (type.ToLower() == "back")
                    {
                        worker.IdCardBack = imageUrl;
                        _logger.LogInformation("更新背面照片: WorkerId={WorkerId}, Url={Url}", workerId, imageUrl);
                    }

                    // 检查是否所有信息都已完整
                    if (!string.IsNullOrEmpty(worker.IdCardFront) &&
                        !string.IsNullOrEmpty(worker.IdCardBack) &&
                        !string.IsNullOrEmpty(worker.RealName) &&
                        !string.IsNullOrEmpty(worker.IdCardNumber))
                    {
                        worker.Status = WorkerStatus.Active;
                        worker.IsVerified = true;
                        _logger.LogInformation("工人认证完成: WorkerId={WorkerId}", workerId);
                    }

                    // 标记实体状态
                    _context.Entry(worker).State = EntityState.Modified;

                    // 保存更改
                    await _context.SaveChangesAsync();

                    // 提交事务
                    scope.Complete();

                    return imageUrl;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "数据库更新失败: WorkerId={WorkerId}, Type={Type}", workerId, type);
                    throw;
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "上传身份证图片失败: WorkerId={WorkerId}, Type={Type}", workerId, type);
            throw;
        }
    }
    private async Task<string> UploadToOss(IFormFile file)
        {
            var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
            var timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
            var randomString = Guid.NewGuid().ToString("N").Substring(0, 8);
            var fileName = $"ID_{timestamp}_{randomString}{extension}";
            var objectName = $"uploads/{fileName}";

            try
            {
                var metadata = new ObjectMetadata
                {
                    ContentType = GetContentType(extension),
                    CacheControl = "no-cache",
                    ContentDisposition = "inline"
                };

                using (var stream = file.OpenReadStream())
                {
                    var putObjectRequest = new PutObjectRequest(_bucketName, objectName, stream, metadata);
                    await Task.Run(() => _ossClient.PutObject(putObjectRequest));
                }

                var imageUrl = $"{_baseUrl.TrimEnd('/')}/{objectName}";
                _logger.LogInformation("文件已成功上传到OSS: {Url}", imageUrl);
                return imageUrl;
            }
            catch (OssException ex)
            {
                _logger.LogError(ex, "OSS上传失败: ErrorCode={ErrorCode}, ErrorMessage={ErrorMessage}",
                    ex.ErrorCode, ex.Message);
                throw;
            }
        }

        private bool IsValidImageExtension(string extension)
        {
            var validExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif" };
            return Array.Exists(validExtensions, e => e.Equals(extension, StringComparison.OrdinalIgnoreCase));
        }

        private string GetContentType(string extension)
        {
            switch (extension.ToLower())
            {
                case ".jpg":
                case ".jpeg":
                    return "image/jpeg";
                case ".png":
                    return "image/png";
                case ".gif":
                    return "image/gif";
                default:
                    return "application/octet-stream";
            }
        }
    }
